package cn.seocoo.platform.common.pay.alipay;


import cn.seocoo.platform.common.config.pay.AlipayConfig;
import cn.seocoo.platform.common.json.JSONObject;
import com.alibaba.fastjson.JSON;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.domain.AlipayTradeAppPayModel;
import com.alipay.api.domain.AlipayTradePagePayModel;
import com.alipay.api.domain.AlipayTradeQueryModel;
import com.alipay.api.domain.AlipayTradeRefundModel;
import com.alipay.api.request.AlipayTradeAppPayRequest;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.alipay.api.request.AlipayTradeQueryRequest;
import com.alipay.api.request.AlipayTradeRefundRequest;
import com.alipay.api.response.AlipayTradeAppPayResponse;
import com.alipay.api.response.AlipayTradePagePayResponse;
import com.alipay.api.response.AlipayTradeQueryResponse;
import com.alipay.api.response.AlipayTradeRefundResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.text.DecimalFormat;
import java.util.HashMap;
import java.util.Map;

/**
 * @Author WuJian
 * @Description //TODO 支付工具类
 * @Date 9:40 2019/11/4
 * @Param
 * @return
 **/
public class AliPayUtils {


    private static final Logger logger = LoggerFactory.getLogger(AliPayUtils.class);


    /**
     * @return java.lang.String
     * @Author WuJian
     * @Description //支付宝订单支付
     * @Date 9:42 2019/11/4
     * @Param [支付来源方式 paySource(1:app;2 pc ),orderMap 自定义的订单信息(Map->字符串), orderNumber 订单号 , totalAmount 订单金额(元),]
     **/
    public static String aliPay(Map<String, Object> orderMsg, String orderNumber, String totalAmount) throws Exception {
        AlipayClient alipayClient = AlipayConfig.initClient();
        //将订单号放到回调参数中，支付宝异步通知接口的参数中就可以取到
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("orderNumber", orderNumber);
        jsonObject.put("orderMsg", orderMsg);
        String orderString = null;
        //如果是APP支付

        logger.warn("-------------------->支付宝APP支付 统一支付下单开始<-------------------------");
        AlipayTradeAppPayRequest requests = new AlipayTradeAppPayRequest();
        //SDK已经封装掉了公共参数，这里只需要传入业务参数。以下方法为sdk的model入参方式
        //(model和biz_content同时存在的情况下取biz_content)。
        AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
        //addModel(model,jsonObject,orderNo,totalAmount);
        /**
         * setPassbackParams 限制字符258位
         */
        //公用回传参数，如果请求时传递了该参数，则返回给商户时会回传该参数。
        // 支付宝只会在同步返回（包括跳转回商户网站）和异步通知时将该参数原样返回。本参数必须进行UrlEncode之后才可以发送给支付宝。
        model.setPassbackParams(JSON.toJSONString(jsonObject));
        //商户网站唯一订单号
        model.setOutTradeNo(orderNumber);
        //对一笔交易的具体描述信息。如果是多种商品，请将商品描述字符串累加传给body。
        model.setBody(AlipayConfig.body);
        //商品的标题/交易标题/订单标题/订单关键字等。
        model.setSubject(AlipayConfig.subject);
        //该笔订单允许的最晚付款时间，逾期将关闭交易。
        // 取值范围：1m～15d。m-分钟，h-小时，d-天，1c-当天（1c-当天的情况下，无论交易何时创建，都在0点关闭）。
        // 该参数数值不接受小数点， 如 1.5h，可转换为 90m。
        model.setTimeoutExpress("10m");
        //model.setTotalAmount(totalAmount);
        model.setTotalAmount("0.01");
        logger.warn("支付宝APP支付  金额是--------->" + totalAmount + "元");
        //销售产品码，商家和支付宝签约的产品码
        //model.setProductCode("QUICK_MSECURITY_PAY");
        requests.setBizModel(model);
        //回调函数
        requests.setNotifyUrl(AlipayConfig.notifyUrl);
        logger.warn("支付宝APP支付 统一下单发送的数据: " + model.getPassbackParams());
        try {
            //这里和普通的接口调用不同，使用的是sdkExecute
            AlipayTradeAppPayResponse response = alipayClient.sdkExecute(requests);
            //就是orderString 可以直接给APP请求，无需再做处理。
            orderString = response.getBody();
            logger.warn("支付宝APP支付 统一下单接受返回的结果: " + orderString);
            if (!response.isSuccess()) {
                return "支付失败";
            }
            logger.warn("-------------------->支付宝APP支付 统一支付下单结束<-------------------------");
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }

        return orderString;
    }

    /**
     * 统一收单线下交易查询
     *
     * @param orderNumber 订单支付时传入的商户订单号,
     * @author duanpj
     * @date: 2019/12/3 12:12
     */
    public static Map<String, String> aliPayOrderQuery(String orderNumber) {
        logger.warn("-------------------->支付宝查询订单信息 开始<-------------------------");
        Map map = new HashMap();
        try {
            AlipayClient alipayClient = AlipayConfig.initClient();
            //创建API对应的request类
            AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
            AlipayTradeQueryModel model = new AlipayTradeQueryModel();
            model.setOutTradeNo(orderNumber);
            request.setBizModel(model);
            //通过alipayClient调用API，获得对应的response类
            AlipayTradeQueryResponse response = alipayClient.execute(request);
            logger.warn("支付宝查询订单信息 返回的数据: " + response.getBody());
            Map<String, Object> jsonToMap = com.alibaba.fastjson.JSONObject.parseObject(response.getBody());
            Map mmap = (Map) jsonToMap.get("alipay_trade_query_response");
            if (!"10000".equals(mmap.get("code"))) {
                map.put("tradeState", "NOTPAY");
            }
            logger.warn("-------------------->支付宝查询订单信息 结束<-------------------------");
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        return map;
    }

    /**
     * @return java.lang.String
     * @Author WuJian
     * @Description // 支付宝退款
     * @Date 9:42 2019/11/4
     * @Param [orderNo, totalAmount]
     **/
    public static Map<String, String> aliRefund(String orderNumber, int totalAmount) throws AlipayApiException {
        logger.warn("-------------------->支付宝交易退款 开始<-------------------------");
        Map map = new HashMap();
        AlipayClient alipayClient = AlipayConfig.initClient();
        //创建API对应的request类
        AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();
        DecimalFormat fnum = new DecimalFormat("##0.00");
        AlipayTradeRefundModel model = new AlipayTradeRefundModel();
        model.setOutTradeNo(orderNumber);
        model.setRefundAmount(fnum.format((float) totalAmount / 100));
        model.setRefundReason("取消订单");
        request.setBizModel(model);
        request.setNotifyUrl(AlipayConfig.notifyUrl);
        //通过alipayClient调用API，获得对应的response类
        AlipayTradeRefundResponse response = alipayClient.execute(request);
        Map<String, Object> jsonToMap = com.alibaba.fastjson.JSONObject.parseObject(response.getBody());
        Map mmap = (Map) jsonToMap.get("alipay_trade_refund_response");
        logger.warn("支付宝交易退款,返回参数-------------------->" + mmap);
        if ("10000".equals(mmap.get("code"))) {
            map.put("buyer_logon_id", mmap.get("buyer_logon_id"));
            map.put("refund_fee", mmap.get("refund_fee"));
            map.put("out_trade_no", mmap.get("out_trade_no"));
            map.put("gmt_refund_pay", mmap.get("gmt_refund_pay"));
        }
        logger.warn("-------------------->支付宝交易退款 结束<-------------------------");
        return map;
    }


}
